﻿using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace OneWorks.Web.Common.ActionResults
{
    public class ComboResult<T> : CustomResult<List<Combo>>
    {
        private readonly string _defaultText;
        private readonly object _defaultValue;
        private readonly IEnumerable<T> _data;
        private readonly bool _isDefault;
        private readonly Dictionary<ComboField, string> dictionary = new Dictionary<ComboField, string>();

        public ComboResult(IEnumerable<T> data, bool isDefault = false, string defaultText = null, object defaultValue = null)
        {
            GetDictionary();
            _data = data ?? new List<T>();
            _isDefault = isDefault;
            _defaultText = defaultText;
            _defaultValue = defaultValue;
        }

        public ComboResult(IEnumerable<T> data, ComboMap<T> comboMap, bool isDefault = false, string defaultText = null,
            object defaultValue = null)
        {

            dictionary = comboMap == null ? new Dictionary<ComboField, string>() : comboMap.GetDictionary();
            _data = data ?? new List<T>();
            _isDefault = isDefault;
            _defaultText = defaultText;
            _defaultValue = defaultValue;
        }

        private void GetDictionary()
        {
            foreach (PropertyInfo property in typeof(T).GetProperties())
            {
                var attrs = property.GetCustomAttributes(false);
                foreach (var tempAttr in attrs.OfType<ComboAttribute>())
                {
                    switch (tempAttr.ComboField)
                    {
                        case ComboField.Text:
                            if (dictionary.ContainsKey(ComboField.Text))
                                dictionary[ComboField.Text] = property.Name;
                            else
                                dictionary.Add(ComboField.Text, property.Name);
                            break;
                        case ComboField.Value:
                            if (dictionary.ContainsKey(ComboField.Value))
                                dictionary[ComboField.Value] = property.Name;
                            else
                                dictionary.Add(ComboField.Value, property.Name);
                            break;
                    }
                }
            }
        }

        public override List<Combo> GetObject()
        {
            var textFieldName = dictionary.ContainsKey(ComboField.Text) ? dictionary[ComboField.Text] : "";
            var valueFieldName = dictionary.ContainsKey(ComboField.Value) ? dictionary[ComboField.Value] : "";
            List<Combo> entities = new List<Combo>();
            if (_isDefault)
            {
                entities.Add(new Combo
                {
                    Text = _defaultText,
                    Value = _defaultValue,
                    Selected = true
                });
            }
            foreach (var data in _data)
            {
                Combo comboEntity = new Combo();
                try
                {
                    if (!string.IsNullOrEmpty(textFieldName))
                        comboEntity.Value =
                            data.GetType().GetProperty(dictionary[ComboField.Value]).GetValue(data, null).ToString();
                    if (!string.IsNullOrEmpty(valueFieldName))
                        comboEntity.Text =
                            data.GetType().GetProperty(dictionary[ComboField.Text]).GetValue(data, null).ToString();
                }
                catch
                {

                }
                entities.Add(comboEntity);

            }
            return entities;
        }
    }
}
